using MediatR;
using Microsoft.EntityFrameworkCore;
using SupplierCustomerManagement.Infrastructure;
using SupplierCustomerManagement.Read.API.Applications.Commands.lambing;
using SupplierCustomerManagement.Read.API.Dtos.Lambing;

namespace SupplierCustomerManagement.Read.API.Applications.CommandHandlters.lambing
{
    public class GetAverageLiveStatsQueryHandler : IRequestHandler<GetAverageLiveStatsQuery, List<AverageLivePointDto>>
    {
        private readonly SupplierDbContext _db;
        private readonly ILogger<GetAverageLiveStatsQueryHandler> _logger;

        public GetAverageLiveStatsQueryHandler(SupplierDbContext db, ILogger<GetAverageLiveStatsQueryHandler> logger)
        {
            _db = db;
            _logger = logger;
        }

        public async Task<List<AverageLivePointDto>> Handle(GetAverageLiveStatsQuery request, CancellationToken cancellationToken)
        {
            // 解析日期
            if (!DateTime.TryParse(request.start, out var startDate))
            {
                startDate = DateTime.UtcNow.Date.AddMonths(-1);
            }
            if (!DateTime.TryParse(request.end, out var endDate))
            {
                endDate = DateTime.UtcNow.Date;
            }
            // 规范到整天范围（含结束日）
            endDate = endDate.Date.AddDays(1).AddTicks(-1);

            var query = _db.LambingRecords.AsNoTracking()
                .Where(r => r.LambingDate >= startDate && r.LambingDate <= endDate);
            if (request.farmId.HasValue)
            {
                var fid = request.farmId.Value;
                query = query.Where(r => r.FarmId == fid);
            }

            var items = await query.Select(r => r.LiveLambs).ToListAsync(cancellationToken);
            var total = items.Count;

            // 暂无“未分娩”基数（需引入配种或群体基数才能计算），先置0
            var notLambedCount = 0;
            var zero = items.Count(x => x == 0);
            var one = items.Count(x => x == 1);
            var ge2 = items.Count(x => x >= 2);

            var points = new List<(string label, int count)>
            {
                ("未分娩", notLambedCount),
                ("0", zero),
                ("1", one),
                ("2", ge2)
            };

            int denom = total == 0 ? 1 : total; // 防止除0，全部为0时比例返回0
            decimal cumulative = 0m;
            var result = new List<AverageLivePointDto>();
            foreach (var p in points)
            {
                decimal ratio = total == 0 ? 0m : Math.Round((decimal)p.count * 100m / denom, 2);
                cumulative = Math.Round(cumulative + ratio, 2);
                result.Add(new AverageLivePointDto
                {
                    label = p.label,
                    count = p.count,
                    ratio = ratio,
                    cumulativeRatio = cumulative
                });
            }

            return result;
        }
    }
}
